//
//  IdiomStore.swift
//  XingCeHelper
//
//  Created by 申铭 on 2022/10/11.
//

import Foundation
import CoreData

let kIdiom = "Idiom"
let kColonString: String = "："
let kColonCharacter: Character = "："

enum WeightOper {
    case add
    /// 减
    case subtract
}

class IdiomStore {
    
    static func saveOrUpdate(str: String) -> ImportResult? {
        var result: ImportResult?
        
        if !str.contains(kColonString) && !str.contains(":") {
            return ImportResult(content: "【\(str)】导入失败，格式不正确。", type: .failure)
        }
        
        let replaceStr = str.replacingOccurrences(of: ":", with: kColonString)
        let contents = replaceStr.split(separator: kColonCharacter)
        
        let title = String(contents.first ?? "")
        
        var explain = ""
        if let separatorIndex = str.firstIndex(of: kColonCharacter) {
            explain = String(replaceStr.suffix(from: separatorIndex))
            explain = String(explain.dropFirst())
        }
        
        var keyPointStr = ""
        if let keyPoints = findKeyPoint(explain) {
            for var keyPoint in keyPoints {
                keyPoint = keyPoint.replacingOccurrences(of: "[", with: "")
                keyPoint = keyPoint.replacingOccurrences(of: "]", with: "")
                keyPointStr.append(keyPoint)
                keyPointStr.append("；")
            }
            keyPointStr = String(keyPointStr.dropLast())
        }
        
        let managedContext = CoreDataStack.shared.managedContext
        if let idiom = find(title: title) { // 有，改
            idiom.explain = explain
            idiom.keyPoint = keyPointStr
            idiom.initial = title.et.getPinyinInitial() // 适配旧版，所以改时也获取下首字母
            
            result = ImportResult(content: "【\(title)】修改成功。", type: .update)
        } else { // 无，加
            let idiom = NSEntityDescription.insertNewObject(forEntityName: kIdiom, into: managedContext) as! Idiom
            idiom.title = title
            idiom.explain = explain
            idiom.keyPoint = keyPointStr
            idiom.weight = 50
            idiom.initial = title.et.getPinyinInitial()
            
            result = ImportResult(content: "【\(title)】导入成功。", type: .success)
        }
        
        do {
            try managedContext.save()
            return result
            print("保存或修改成功")
        } catch {
            print("操作失败：\(error)")
            return nil
        }
    }
    
    static func query() -> [Idiom] {
        let managedContext = CoreDataStack.shared.managedContext

        let fetchRequest = NSFetchRequest<Idiom>(entityName: kIdiom)
//        fetchRequest.fetchLimit = 10
        let predicate = NSPredicate(value: true)
        fetchRequest.predicate = predicate
        
        let sortDesc = NSSortDescriptor(key: "weight", ascending: false)
        fetchRequest.sortDescriptors = [sortDesc]

        do {
            let fetchedObjects = try managedContext.fetch(fetchRequest)
            return fetchedObjects
        } catch {
            print("错误：\(error)")
        }
        
        return [Idiom]()
    }
    
    /// 分组 + 排序 查询全部成语
    /// - Returns: NSFetchedResultsController
    static func query() -> NSFetchedResultsController<Idiom> {
        let managedContext = CoreDataStack.shared.managedContext

        let fetchRequest = NSFetchRequest<Idiom>(entityName: kIdiom)
        let predicate = NSPredicate(value: true)
        fetchRequest.predicate = predicate
        
        // 排序
        let initialSortDesc = NSSortDescriptor(key: "initial", ascending: true)
        fetchRequest.sortDescriptors = [initialSortDesc]
        
        // 查询并分组
        let fetchedRC = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: managedContext, sectionNameKeyPath: "initial", cacheName: nil)
        
        do {
            try fetchedRC.performFetch()
        } catch let error as NSError {
            print("Error: \(error.userInfo)")
        }

        return fetchedRC
    }
    
    static func findKeyPoint(_ str: String) -> Array<String>? {
        let pattern = "(\\[[\\w\\W]*\\])" // 创建拼配规则：[xxx]
        // 创建这正则表达式对象
        let regex = try? NSRegularExpression(pattern: pattern, options: [.dotMatchesLineSeparators]);
        // 匹配字符串中的内容
        guard let results = regex?.matches(in: str, options: [], range: NSRange(location: 0, length: str.count)) else {
            return nil
        }
              
        var keyPoints = [String]()
        for result in results {
            let tmpStr = (str as NSString).substring(with: result.range)
            keyPoints.append(tmpStr)
        }
        return keyPoints
    }
    
    /// 更改权重
    /// - Parameters:
    ///   - weight: 权重
    ///   - oper: 操作 1:加 2:减
    static func changeWeight(title: String, weight: Int, oper: WeightOper) {
        guard let idiom = find(title: title) else { return }
        
        if oper == .add { // 加
            idiom.weight = idiom.weight + Int32(weight)
        } else if oper == .subtract { // 减
            idiom.weight = idiom.weight - Int32(weight)
        }
        
        do {
            try CoreDataStack.shared.managedContext.save()
        } catch {
            print("错误：\(error)")
        }
    }
    
    static func find(title: String) -> Idiom? {
        let managedContext = CoreDataStack.shared.managedContext
        let fetchRequest = NSFetchRequest<Idiom>(entityName: kIdiom)
        let predicate = NSPredicate(format: "title == %@", title) // 设置查询条件
        fetchRequest.predicate = predicate

        do {
            let fetchedObjects = try managedContext.fetch(fetchRequest)
            return fetchedObjects.first
        } catch {
            print("错误：\(error)")
        }
        
        return nil
    }
    
    static func getCount() -> Int {
        let fetchquest = NSFetchRequest<NSFetchRequestResult>(entityName: kIdiom)
        do {
            return try CoreDataStack.shared.managedContext.count(for: fetchquest)
        } catch {
            print("错误：\(error)")
        }
        return 0
    }
    
    /// 删除
    /// - Parameter title: 标题
    static func delete(title: String) {
        let managedContext = CoreDataStack.shared.managedContext
        if let idiom = find(title: title) {
            managedContext.delete(idiom)
        }
        do {
            try managedContext.save()
            print("操作成功")
        } catch {
            print("操作失败：\(error)")
        }
    }
    
    static func deleteAll() {
        let managedContext = CoreDataStack.shared.managedContext
        let deleteFetch = NSFetchRequest<NSFetchRequestResult>(entityName: kIdiom)
        let deleteRequest = NSBatchDeleteRequest(fetchRequest: deleteFetch)
        deleteRequest.resultType = .resultTypeObjectIDs
        
        do {
            let result = try managedContext.execute(deleteRequest) as! NSBatchDeleteResult
            let changes: [AnyHashable: Any] = [
                NSDeletedObjectsKey: result.result as! [NSManagedObjectID]
            ]
            // 更新内存内容，否则无法刷新tableview中的数据
            NSManagedObjectContext.mergeChanges(fromRemoteContextSave: changes, into: [managedContext])
            try managedContext.save()
            print("操作成功")
        } catch {
            print("操作失败：\(error)")
        }
        
    }
}
